﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Text;
using System.Xml;

namespace Hsinchu.Utility
{
    /*
     * XML处理类
     */
    public class XMLHelper
    {

        /// <summary>
        /// 插入一个新节点
        /// </summary>
        /// <param name="docPath">xml文档路径 eg: /config/global.xml</param>
        /// <param name="parentNodePath">新节点所属的父节点XPath路径,eg：//node//</param>
        /// <param name="xmlNode">新节点键值对 Dictionary类型</param>
        /// <returns>bool</returns>
        public static bool InsertNode(string docPath,string parentNodePath,Dictionary<string,string> xmlNode)
        {
            try
            {
                //获得XmlDocument对象
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(docPath);

                //获得父节点
                XmlNode parentNode = xmlDoc.SelectSingleNode(parentNodePath);

                //循环创建节点并添加
                foreach (KeyValuePair<string, string> item in xmlNode)
                {
                    //判断节点是否存在
                    XmlNodeList nodeList = xmlDoc.SelectNodes(parentNodePath + "//" + item.Key);
                    if (nodeList.Count > 0)
                    {
                        //修改
                        UpdateNode(xmlDoc, parentNodePath + "//" + item.Key, item.Value);
                    }
                    else
                    {
                        //添加
                        XmlNode xn = xmlDoc.CreateNode(XmlNodeType.Element, item.Key, null);
                        xn.InnerText = item.Value;                        
                        parentNode.AppendChild(xn);
                    }
                }
                xmlDoc.Save(docPath);
                return true;
            }
            catch (XmlException xe)
            {
                ErrorHandle.Log(xe.Message);
                return false;                
                throw (xe);
            }
            catch (System.IO.FileLoadException fle)
            {
                ErrorHandle.Log(fle.Message);
                return false;
            }
            catch (System.IO.FileNotFoundException ffe)
            {
                ErrorHandle.Log(ffe.Message);
                return false;
            }
            catch (Exception e)
            {
                ErrorHandle.Log(e.Message);
                return false;
            }           
        }

        /// <summary>
        /// 插入节点及该节点的属性
        /// </summary>
        /// <param name="docPath">xml文档路径 eg: /config/global.xml</param>
        /// <param name="parentNodePath">新节点所属的父节点XPath路径,eg：//node//</param>
        /// <param name="value">新节点属性键值对 Dictionary类型</param>
        /// <returns>bool</returns>
        public static bool InsertNodeAttribute(string docPath, string parentNodePath, Dictionary<string, string> value)
        {
            try
            {
                //获得XmlDocument对象
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(docPath);
                //获得父节点
                XmlNode parentNode = xmlDoc.SelectSingleNode(parentNodePath);
                foreach (KeyValuePair<string, string> item in value)
                {
                    XmlAttribute xa = xmlDoc.CreateAttribute(item.Key);
                    xa.Value = item.Value;
                    parentNode.Attributes.Append(xa);
                }
                xmlDoc.Save(docPath);
                return true;
            }
            catch (XmlException xe)
            {
                ErrorHandle.Log(xe.Message);
                return false;
                throw (xe);
            }
            catch (System.IO.FileLoadException fle)
            {
                ErrorHandle.Log(fle.Message);
                return false;
            }
            catch (System.IO.FileNotFoundException ffe)
            {
                ErrorHandle.Log(ffe.Message);
                return false;
            }
            catch (Exception e)
            {
                ErrorHandle.Log(e.Message);
                return false;
            }       
        }

        /// <summary>
        /// 修改节点信息
        /// </summary>
        /// <param name="doc">要修改的xml文档对象</param>
        /// <param name="Xpath">XPath路径</param>
        /// <param name="value">该节点的新值</param>
        public static void UpdateNode(XmlDocument xmlDoc, string Xpath,string value)
        {
            try
            {
                XmlNode node = xmlDoc.SelectSingleNode(Xpath);
                node.InnerText = value;
            }
            catch (XmlException e)
            {
                ErrorHandle.Log(e.Message);
                throw (e);
            }
        }

        /// <summary>
        /// 根据指定Xpath和节点值查询节点是否存在
        /// </summary>
        /// <param name="docPath"></param>
        /// <param name="parentNodePath"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsExistNode(string docPath, string parentNodePath, string value)
        {
            //获得XmlDocument对象
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(docPath);
            //获得父节点
            XmlNode parentNode = xmlDoc.SelectSingleNode(parentNodePath);
            XmlNodeList nodeList = xmlDoc.SelectNodes(parentNodePath+"//"+value);
            if (nodeList.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        public static DataTable GetXmlToDataTable (string docPath, string parentNodePath,DataTable dtschema)
        {
            //获得XmlDocument对象            
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(docPath);
            //判断节点是否存在
            XmlNode node = xmlDoc.SelectSingleNode(parentNodePath);
            foreach (XmlNode xn in node.ChildNodes)
            {
                DataRow dr = dtschema.NewRow();
                XmlAttributeCollection xc = xn.Attributes;
                foreach (XmlAttribute xa in xc)
                {
                    dr[xa.Name] = xa.InnerXml;                    
                }
                dtschema.Rows.Add(dr);
            }
            return dtschema;
        }
    }
}
